package com.ruoyi.keno.service.impl;

import java.io.IOException;
import java.util.*;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.cache.redis.util.RedisUtils;
import com.ruoyi.keno.enums.AreaEnums;
import com.ruoyi.keno.enums.BigEnums;
import com.ruoyi.keno.enums.SingleEnums;
import com.ruoyi.keno.service.IKenoGuessService;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.ruoyi.keno.mapper.KenoHistoryMapper;
import com.ruoyi.keno.entity.KenoHistory;
import com.ruoyi.keno.service.IKenoHistoryService;
import com.ruoyi.common.core.text.Convert;
import tk.mybatis.mapper.entity.Example;

/**
 * 【请填写功能名称】Service业务层处理
 * 
 * @author ziyeibin
 * @date 2020-11-06
 */
@Service
public class KenoHistoryServiceImpl implements IKenoHistoryService 
{
    @Autowired
    private KenoHistoryMapper kenoHistoryMapper;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    private IKenoGuessService kenoGuessService;

    Queue<KenoHistory> lb45Queue =  new LinkedList<>();
    Queue<KenoHistory> lb60Queue =  new LinkedList<>();
    Queue<KenoHistory> lb90Queue =  new LinkedList<>();


    /**
     * 根据city代码不断更新历史表
     * @param cityCode
     */
    @Override
    public void getDataAcquisition(Integer cityCode) {
        String cityName = AreaEnums.getCityNameByCode(cityCode);
        Long lbNo =  redisUtils.get(cityName)==null?0L:(Long)redisUtils.get(cityName);

        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        //2.创建get请求，相当于在浏览器地址栏输入 网址
        HttpGet request = new HttpGet("http://www.lb-keno-game.com/api/Current/"+cityCode+"?_="+System.currentTimeMillis());
        try {
            //3.执行get请求，相当于在输入地址栏后敲回车键
            response = httpClient.execute(request);
            //4.判断响应状态为200，进行处理
            if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                //5.获取响应内容

                    HttpEntity httpEntity = response.getEntity();
                    String html = EntityUtils.toString(httpEntity, "utf-8");
                    KenoHistory keno = this.StrSplit(cityCode,html);

                    if(keno.getIssueNo().equals(lbNo)){
                        return;
                    }

                    if(keno.getIssueNo()>lbNo && lbNo != 0l && lbNo + 1 != keno.getIssueNo()) {
                        if (keno.getArea().equals(AreaEnums.LB45.getCityName())) {
                            this.getHistory(AreaEnums.LB45, lbNo, keno.getIssueNo());
                        } else if (keno.getArea().equals(AreaEnums.LB60.getCityName())) {
                            this.getHistory(AreaEnums.LB60, lbNo, keno.getIssueNo());
                        } else if (keno.getArea().equals(AreaEnums.LB90.getCityName())) {
                            this.getHistory(AreaEnums.LB90, lbNo, keno.getIssueNo());
                        }
                    }else{
                        if(kenoHistoryMapper.selectByPrimaryKey(keno.getIssueNo())==null){
                            keno.setAddType(1);
                            kenoHistoryMapper.insertSelective(keno);
                            redisUtils.set(cityName, keno.getIssueNo(), 0);
                            //ddddd
                            Queue<KenoHistory> queueList = this.queveList(keno);
                            kenoGuessService.guessNextResult(new ArrayList(queueList));
                        }
                    }



//                redisTemplate.opsForList().rightPush("yourQueue",keno);
//                redisTemplate.opsForList().range()
//                redisTemplate.opsForList().leftPop("yourQueue");

         //       System.out.println(html);
            } else {
                //如果返回状态不是200，比如404（页面不存在）等，根据情况做处理，这里略
                System.out.println("返回状态不是200");
                System.out.println(EntityUtils.toString(response.getEntity(), "utf-8"));
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //6.关闭
            HttpClientUtils.closeQuietly(response);
            HttpClientUtils.closeQuietly(httpClient);
        }
    }
    @Async
    void getHistory(AreaEnums area, Long start, Long issueNo){

        for(long i=start+1;i<issueNo;) {
            CloseableHttpClient httpClient = HttpClients.createDefault();
            CloseableHttpResponse response = null;
            //http://www.lb-keno-game.com/api/Last/1/1907116?_=1605833893353
            HttpGet request = new HttpGet("http://www.lb-keno-game.com/api/Last/" + area.getCityCode()+"/"+ i + "?_=" + System.currentTimeMillis());
            try {
                //3.执行get请求，相当于在输入地址栏后敲回车键
                response = httpClient.execute(request);
                //4.判断响应状态为200，进行处理
                if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                    HttpEntity httpEntity = response.getEntity();
                    String html = EntityUtils.toString(httpEntity, "utf-8");
                    List<KenoHistory> kenoList = this.StrArrSplit(area.getCityCode(),html);
                    if(CollectionUtil.isNotEmpty(kenoList)) {
                        i = kenoList.get(0).getIssueNo()+1;
                        redisUtils.set(area.getCityName(), kenoList.get(0).getIssueNo()+1, 0);
                        for(KenoHistory keno:kenoList) {
                            if(keno.getIssueNo()==start || keno.getIssueNo()==issueNo){
                                continue;
                            }
                            if(kenoHistoryMapper.selectByPrimaryKey(keno.getIssueNo())==null){

                                System.out.println("补充期号：" + keno.getArea() + " " + keno.getIssueNo());
                                keno.setAddType(2);
                                kenoHistoryMapper.insertSelective(keno);
                            }else{
                                break;
                            }


                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    private KenoHistory StrSplit(Integer cityCode,String jsonStr){
        KenoHistory keno = new KenoHistory();
        JSONObject json = JSON.parseObject(jsonStr);
        keno.setArea(AreaEnums.getCityNameByCode(cityCode));
        keno.setIssueNo(json.getJSONObject("d").getLong("dn"));
        keno.setNum(json.getJSONObject("d").getString("r"));
        this.createKeno(keno);
        return keno;
    }

    private List<KenoHistory> StrArrSplit(Integer cityCode,String jsonStr){
        JSONObject json = JSON.parseObject(jsonStr);
        JSONArray arr = json.getJSONObject("d").getJSONArray("r");
        List<KenoHistory> list = new ArrayList<>();
        for(int i=0;i<arr.size();i++){
            JSONObject jsonObject = arr.getJSONObject(i);
            KenoHistory keno = new KenoHistory();
            keno.setArea(AreaEnums.getCityNameByCode(cityCode));
            keno.setIssueNo(jsonObject.getLong("dn"));
            keno.setNum(jsonObject.getString("dr"));
            this.createKeno(keno);
            list.add(keno);
        }
        return list;
    }

    private void createKeno( KenoHistory keno){
        int[] num = StrUtil.splitToInt(keno.getNum(), ",");
        int sum = Arrays.stream(num).sum();
        keno.setTotal(sum);
        if(sum<810){
            keno.setBig(BigEnums.小.getCode());
        }else if(sum == 810){
            keno.setBig(BigEnums.中810.getCode());
        }else if(sum > 810){
            keno.setBig(BigEnums.大.getCode());
        }
        if(sum%2==0){
            keno.setSingle(SingleEnums.双.getCode());
        }else{
            keno.setSingle(SingleEnums.单.getCode());
        }

        if(sum>=210 && sum<=695){
            keno.setWuxing("金");
        }else if(sum>=696 && sum<=763){
            keno.setWuxing("木");
        }else if(sum>=764 && sum<=855){
            keno.setWuxing("水");
        }else if(sum>=856 && sum<=923){
            keno.setWuxing("火");
        }else if(sum>=924){
            keno.setWuxing("土");
        }
        keno.setCreateTime(new Date());
    }

    private Queue<KenoHistory> queveList(KenoHistory keno){
        Queue<KenoHistory> queue = null;
        String key = null;
        if (keno.getArea().equals(AreaEnums.LB45.getCityName())) {
            queue = lb45Queue;
      //      key = AreaEnums.LB45.getCityName()+"List";
        } else if (keno.getArea().equals(AreaEnums.LB60.getCityName())) {
            queue = lb60Queue;
   //         key = AreaEnums.LB60.getCityName()+"List";
        } else if (keno.getArea().equals(AreaEnums.LB90.getCityName())) {
            queue = lb90Queue;
    //        key = AreaEnums.LB90.getCityName()+"List";
        }
//        queue = (Queue<KenoHistory>) redisUtils.get(key);
//        if(queue==null){
//            queue = new LinkedList<>();
//        }
        if(queue.size()==0){
            Example example = new Example(KenoHistory.class);
            example.and().andEqualTo("area",keno.getArea()).andGreaterThan("issueNo",keno.getIssueNo()-100).andLessThan("issueNo",keno.getIssueNo());
            // 排序
            example.orderBy("issueNo").asc();

            List<KenoHistory> list = kenoHistoryMapper.selectByExample(example);
            for(KenoHistory kenoh : list){
                queue.add(kenoh);
            }
        }
        if(queue.size()>99){
            queue.poll();
        }
        queue.add(keno);
 //       redisUtils.set(key, queue, 0);
        return queue;
    }

}
